using System;
using EnvDTE;
using Extensibility;
using System.Collections ;
using System.Text;
using System.IO ;

using System.Windows .Forms ;
using System.CodeDom .Compiler ;
using System.CodeDom;

using System.Xml ;
using System.Text .RegularExpressions ;
using AopDotNet.CodeModelXMLTreeBuilder ;
using AopDotNet.AspectWeaver ;

namespace AopDotNet
{
		namespace Editor
		{
			public class CodeEditor
			{
				static public CodeModelBuilder AdvisedCodeModelTree;
				
				static public void AddToBases(CodeClass theClass,string strNewBase ,bool IsInterface,ICodeGenerator codeGen ,EditingMonitor monitor)
				{
					/*REMF*/	
					EditPoint st=theClass.StartPoint .CreateEditPoint ();
					monitor.UpdateEditPoint (ref st);
					EditPoint end=theClass.EndPoint.CreateEditPoint ();
					monitor.UpdateEditPoint (ref end);
					string strClass=st.GetText (end );	
					string strBases="",strBody="",strAtt="";

					//get the bases section ex vb: Inherits xx Implements IX,IY
					CodeInspector.PartitionClass (theClass.Name ,strClass,ref strBases,ref strBody,ref strAtt,codeGen);
					ArrayList basesList=CodeInspector.ExtractBasesNames(strBases,codeGen);
					if (basesList.Count  !=0)
					{
						AddNewBaseToClassWithBases(theClass,strNewBase,strBases,basesList,strBody,IsInterface,codeGen,monitor);
					}
					else  //deosn't have base classes
					{
						AddNewBaseToClassWithoutBases(theClass,strNewBase,strBody,IsInterface,codeGen,monitor);
					}
				}

				static void AddNewBaseToClassWithoutBases(CodeClass theClass,string strNewBase,string strBody,bool IsInterface,ICodeGenerator codeGen,EditingMonitor monitor)
				{
					//generate a class with the new base
					CodeTypeDeclaration t=new CodeTypeDeclaration (theClass.Name);
					t.IsClass =true;
					t.TypeAttributes=0;
					t.BaseTypes.Add (strNewBase);
					t.Members .Add (new CodeSnippetTypeMember (strBody));
			
					string newClassDecl=LanguageEngine.GenerateCodeFromType (t,codeGen);
					if (IsInterface)
					{
						//if interface use the implement keyword
						string interfaceImplementSyntax=LanguageEngine.KeywordInClassImplementInterface(codeGen);
						if (interfaceImplementSyntax!="")
							newClassDecl =Regex.Replace (newClassDecl,LanguageEngine.KeywordInClassInheritClass(codeGen),interfaceImplementSyntax,RegexOptions.IgnoreCase );/*Error Handling*///j is case sensitive
					}

					//int indexAfterClassName=newClassDecl.IndexOf (theClass.Name )+theClass.Name .Length ;
					//int bodyIndex=newClassDecl.IndexOf (strBody);

					//the code that contains the base classes inheritance is usually after
					//the name of the class and before its body
					string strBasescode=CodeInspector .GetBases (theClass.Name ,newClassDecl,codeGen);
					//string strBasescode=newClassDecl.Substring (indexAfterClassName,bodyIndex-indexAfterClassName);

					/*string[] keywords=LanguageEngine.KeywordsAndDelimetersInClassDeclarationWithoutBases(codeGen );
					for (int i=0;i<keywords.Length ;i++)
					{
						if (keywords[i].Length !=0)
							strBasescode=strBasescode.Replace (keywords[i],"");
					}*/
			
					//st=theClass.GetStartPoint (vsCMPart.vsCMPartWhole  ).CreateEditPoint();
					/*REMF*/
					EditPoint st=theClass.StartPoint.CreateEditPoint();
					monitor.UpdateEditPoint (ref st);
				
					EditPoint end =theClass.GetEndPoint (vsCMPart .vsCMPartBody ).CreateEditPoint ();
					monitor.UpdateEditPoint (ref end);
					/*REMF*/
					int oldClassNameIndex=st.GetText (end).IndexOf (theClass.Name);
					st.MoveToAbsoluteOffset (st.AbsoluteCharOffset +oldClassNameIndex+theClass.Name .Length);
					try
					{
						monitor.StartLog(ref st,true);
						st.Insert ("\n "+strBasescode +"\n");/*Inser*/
						monitor.EndLog(ref st);
					}
					catch(Exception expp)
					{
						string expmes=expp.Message ;
					}
						
			
				}
				static void AddNewBaseToClassWithBases(CodeClass theClass,string strNewBase,string strBases,ArrayList basesList,string strBody,bool IsInterface,ICodeGenerator codeGen,Editor.EditingMonitor monitor)
				{
					/*REMF*/
					EditPoint st=theClass.StartPoint .CreateEditPoint ();
				
					string classInheritsKeyword=LanguageEngine.KeywordInClassInheritClass (codeGen);
					string classImplementKeyword=LanguageEngine.KeywordInClassImplementInterface(codeGen);
					//vb uses inherits for classes and implements for interfaces
	
					//check to see is the class has a base class not interface
					Match matchBaseClass=Regex.Match (strBases,classInheritsKeyword,RegexOptions.IgnoreCase ); //c# & jsharp are case sensitive
					if (matchBaseClass.Success &&!IsInterface  )         
						return;//already has a base class and we want to add another /*Error Handling*/
			
					//generate a class with the updated base
					CodeTypeDeclaration t=new CodeTypeDeclaration (theClass.Name );
					t.IsClass =true;
					t.TypeAttributes=0;

					//if the new base is class it must be the first in the bases list
					if (!IsInterface)
					{
						t.BaseTypes .Add (strNewBase);
						for (int j=0;j<basesList.Count  ;j++)
						{
							if (((string)basesList[j])!="")
								t.BaseTypes.Add( (string)basesList[j]);
						}
					}
					else
					{
						for (int j=0;j<basesList.Count  ;j++)
						{
							if (((string)basesList[j])!="")
								t.BaseTypes.Add((string) basesList[j]);
						}
						t.BaseTypes .Add (strNewBase);
					}

					//if the old and the new base are all interfaces remove any inherit keyword
					if (IsInterface&&!matchBaseClass.Success )
						t.UserData .Add ("hasExtendsClause",(System.Boolean )false);
			
					string strPattern=LanguageEngine.GenerateCodeFromType  (t,codeGen);

					//if the old and the new base are all interfaces remove any inherit keyword
					//3'aaaaaaaaaaaaaaaalaaaaaaaaaaaaaaaaaaaaat use userData mesh faker feen
					//if (IsInterface&&!matchBaseClass.Success )
					//	strPattern=Regex.Replace (strPattern,classInheritsKeyword,classImplementKeyword,RegexOptions.IgnoreCase);
		
					//get the generated base list
					string newBases=CodeInspector.GetBases(theClass.Name ,strPattern,codeGen);
		
					//st=theClass.GetStartPoint (vsCMPart.vsCMPartWhole ).CreateEditPoint();
					//st=theClass.StartPoint.CreateEditPoint();
					//int index=st.GetText (theClass.GetEndPoint (vsCMPart .vsCMPartBody ).CreateEditPoint ()).IndexOf (strBody);
					//if (index!=-1)
					//  st.MoveToAbsoluteOffset (st.AbsoluteCharOffset +index);
					//else
					//	index=0;
				
					//TextPoint endpoint=theClass.GetStartPoint (vsCMPart.vsCMPartBody );
					/*REMF*/

					monitor.UpdateEditPoint (ref st);
					EditPoint endpoint=theClass.EndPoint.CreateEditPoint ();
					monitor.UpdateEditPoint (ref endpoint);
				
					//	EditPoint po=theClass.GetStartPoint (vsCMPart .vsCMPartBody ).CreateEditPoint ();
					//	string gg=po.GetText (st);
			
				
					TextRanges r=null;
					st.ReplacePattern (endpoint,strBases,newBases+"\n",(int)vsFindOptions .vsFindOptionsNone,ref r );
			
				}

				static public void AddAttributeToMethod(CodeFunction theFunction,CodeAttribute theAttribute)
				{
				}
		
				static public void AddMethodToClass(CodeClass theClass,CodeFunction theFunction,bool implementInterfaceMethod,string implementedInterfaceName,ICodeGenerator codeGen,EditingMonitor monitor)
				{
					/*Error Handling*/ //check to see if a method with the same name and signature exists
			
					EditPoint ep=theFunction.StartPoint.CreateEditPoint  ();
					monitor.UpdateEditPoint (ref ep);
					EditPoint end=theFunction.EndPoint .CreateEditPoint ();
					monitor.UpdateEditPoint (ref end);
					StringBuilder funcBody=new StringBuilder(ep.GetText (end));
										
					bool removeFirstParam=HandleFirstParamCase(theClass,theFunction,ref funcBody,implementInterfaceMethod,implementedInterfaceName,codeGen,monitor);
				
					//get the whole function text
					
					//TextPoint endText=theClass.GetEndPoint (vsCMPart.vsCMPartWhole  );
					//	TextPoint endText=theClass.EndPoint;

					//move to the end of the class where you'll insert the function
					EditPoint endPoint=theClass.GetEndPoint(vsCMPart.vsCMPartBody ) .CreateEditPoint ();
					monitor.StartLog (ref endPoint,false);
					
					//if there 's no special syntax for an interface method then insert the function
					if (!implementInterfaceMethod || (implementInterfaceMethod &&!IsMethodImplementInterfaceDiffrent (codeGen)))
					{
						endPoint.LineUp (1);
						endPoint.EndOfLine ();
						endPoint.Insert ("\n");
						endPoint.Insert (RemoveFirstParameterFromFunction(ref funcBody,removeFirstParam ));/*Inser*/
						monitor.EndLog (ref endPoint);
						return;
					}
									
					string strImplements=" "+LanguageEngine .KeywordInClassImplementInterface (codeGen)+" "+implementedInterfaceName +"."+theFunction .Name;

					//TextPoint strtBodyPoint=theFunction.GetStartPoint(vsCMPart.vsCMPartBody);
					EditPoint stPoint=theFunction.GetStartPoint(vsCMPart.vsCMPartBody).CreateEditPoint ();
					monitor.UpdateEditPoint (ref stPoint);
					
					//get the function header
					string fheader=ep.GetText (stPoint);

					//if the header doesn't contain the implements then add it 
					if (fheader.IndexOf (strImplements)==-1)/*Missing*/ //insensitive comparison
					{
						/*REMN*/
						int i=ep.LineCharOffset ;
						//ep.MoveToLineAndOffset (ep.Line ,ep.LineLength-1/* ep.LineLength+1*/ /*Test*/ );
						ep.EndOfLine ();
						EditPoint endofLine=ep.CreateEditPoint ();
						endofLine.CharLeft (3);
						string hht=endofLine.GetText (ep);
						//while (Regex.Match (ep.GetText (endofLine),"\n").Success ==false)
						//{
						//	ep.CharLeft (1);
						//}

						int j=ep.LineCharOffset  -i;
						string strFuncBody=funcBody .ToString ();
						if (strFuncBody[j]!='\r')
						{
							j--;
							if (strFuncBody[j]=='\n')
								j--;
						}
							
								funcBody.Insert (j,strImplements );
						endPoint.LineUp (1);
						endPoint.EndOfLine ();
						endPoint.Insert ("\n");
						endPoint.Insert (RemoveFirstParameterFromFunction(ref funcBody,removeFirstParam ));
						/*Inser*/
					
					}
					monitor.EndLog (ref endPoint);

				}
				
			/// <summary>
			/// introducing a method to a class then must take care of binding the parameters
			/// </summary>
			/// <param name="theClassName">the class to which the function is introduced</param>
			/// <param name="theFunction">the introduced function</param>
			/// <param name="isInInterface">whether the function belongs to an interface or not</param>
			/// <param name="interfaceName">the name of the interface to which the method belongs</param>
			/// <param name="monitor"></param>
			/// <returns></returns>
				static bool HandleFirstParamCase(CodeClass theClass,CodeFunction theFunction,ref StringBuilder funcBody,bool isInInterface,string interfaceName,ICodeGenerator codeGenerator,EditingMonitor monitor)
				{
					//get the whole function text
					
					if (isInInterface)  //interface method
					{
						//Get the interface method 
						XmlNode theInterfaceFunctionNode=CodeEditor.AdvisedCodeModelTree.GetXmlDocument ().SelectSingleNode (@"//interface[@name='"+interfaceName+"']/methods/method[@name='"+theFunction.Name  +@"']");
						if (theInterfaceFunctionNode!=null)
						{
							//check its parameters
							XmlNodeList paramsNodes=theInterfaceFunctionNode.SelectNodes ("parameters/parameter");
							if (paramsNodes.Count < theFunction.Parameters.Count )
							{
								// there's  additional parameters in the introduced function
								BindFirstParameter(theClass,theFunction,ref funcBody,codeGenerator,monitor);
								return true;
							}
						}
					}
					else
					{
						//not an interface method then check if it's introduced and has the attribute hascp
						XmlNode theIntroducedMethodNode=CodeEditor.AdvisedCodeModelTree.GetXmlDocument ().SelectSingleNode (@"//class[@name='"+theClass.Name+"']/introductions/method[@name='"+theFunction.Name +"']");
						if (theIntroducedMethodNode!=null)
						{
							XmlAttribute hasContextParam=theIntroducedMethodNode.Attributes ["hascp"];
							if (hasContextParam!=null&&hasContextParam.Value =="true")
							{
								//if hascp true then the first parameter is context param bind it to this
								BindFirstParameter(theClass,theFunction,ref funcBody,codeGenerator,monitor);
								return true;
								/*string strQuery="//aspect/methods/method[@name='"+theFunction.Name+"']/parameters/parameter[position()=1]";
								string firstParamName=CodeEditor.AdvisedCodeModelTree.GetXmlDocument ().SelectSingleNode (strQuery+"/@name").Value ;
								string firstParamType=CodeEditor.AdvisedCodeModelTree.GetXmlDocument ().SelectSingleNode (strQuery+"/@type").Value ;
								
								if (CheckFirstParamBindability(theClass,firstParamType ,codeGenerator,monitor  )==false)
								{
									string strMsg="The Parameter "+firstParamName+" of the Function "+theFunction.Name+ " can't be used as a Context Param becuase it has incompatable type";
									throw new  ArgumentException (strMsg);
								}
								RemoveFirstParameterFromFunction(ref funcBody);
								CodeThisReferenceExpression thisExp=new CodeThisReferenceExpression ();
								StringWriter swThisExp=new StringWriter ();
								codeGenerator .GenerateCodeFromExpression (thisExp,swThisExp,null);
								ReplaceArgumentName(firstParamName,ref funcBody,swThisExp.ToString (),codeGenerator);*/
							}
						
						}
						
					}
					return false;
				}
				/// <summary>
				/// 
				/// </summary>
				/// <param name="theClass">the class to which the function will be introduced</param>
				/// <param name="theFunction">the function to be introduced</param>
				/// <param name="strFunction">the function text</param>
				/// <param name="codeGenerator"></param>
				/// <param name="monitor"></param>
				static void BindFirstParameter(CodeClass theClass,CodeFunction theFunction,ref StringBuilder funcBody,ICodeGenerator codeGenerator,EditingMonitor monitor)
				{
							//get the first param name   /*Missing use IDS not names!!*/
					string strQuery="//aspect/methods/method[@name='"+theFunction.Name+"']/parameters/parameter[position()=1]";
					string firstParamName=CodeEditor.AdvisedCodeModelTree.GetXmlDocument ().SelectSingleNode (strQuery+"/@name").Value ;
					string firstParamType=CodeEditor.AdvisedCodeModelTree.GetXmlDocument ().SelectSingleNode (strQuery+"/@type").Value ;
								
					if (CheckFirstParamBindability(theClass,firstParamType ,codeGenerator,monitor  )==false)
					{
						string strMsg="The Parameter "+firstParamName+" of the Function "+theFunction.Name+ " can't be used as a Context Param becuase it has incompatable type";
						throw new  ArgumentException (strMsg);
					}
					//RemoveFirstParameterFromFunction(ref funcBody);
					CodeThisReferenceExpression thisExp=new CodeThisReferenceExpression ();
					StringWriter swThisExp=new StringWriter ();
					codeGenerator .GenerateCodeFromExpression (thisExp,swThisExp,null);
					ReplaceArgumentName(firstParamName,ref funcBody,swThisExp.ToString (),codeGenerator);
					
				}
				static string RemoveFirstParameterFromFunction(ref StringBuilder strFunction,bool remove)
				{
					if (remove)
					{										
						int startIndex=strFunction.ToString ().IndexOf ("(")+1;
						int endParamsIndex=strFunction.ToString ().IndexOf (")");
						int endFirstParamIndex=strFunction.ToString ().IndexOf (",");
						int len=0;
						if (endFirstParamIndex<endParamsIndex)
						{
							if (endFirstParamIndex==-1)
								len=endParamsIndex-startIndex;
							else
								len=endFirstParamIndex-startIndex+1;
						}
						 
						strFunction.Remove (startIndex,len );
					}
					return strFunction.ToString ();
				}

				static void ReplaceArgumentName(string oldArg,ref StringBuilder function,string newArg,ICodeGenerator codeGenerator)
				{
					CodeArgumentReferenceExpression argRefExpr=new CodeArgumentReferenceExpression (@"(?<bef>\W)"+oldArg+@"(?<aft>\W)" );
						
					StringWriter swArgRefExpr=new StringWriter ();
					codeGenerator .GenerateCodeFromExpression (argRefExpr,swArgRefExpr,null);
					Match matchedArgRef=Regex.Match  (function.ToString (),swArgRefExpr.ToString ());
					int replacement=0;
					while (matchedArgRef.Success )
					{
						function.Replace (oldArg,newArg,matchedArgRef.Index +replacement ,matchedArgRef.Length );
						replacement +=newArg.Length -oldArg.Length ;
						matchedArgRef=matchedArgRef.NextMatch ();
					}
				}
		
				static bool CheckFirstParamBindability(CodeClass theClass,string paramType,ICodeGenerator codeGenerator,EditingMonitor monitor)
				{
				
					string className=theClass.Name  ;
				
					//check if they are the same type
					Match m=Regex.Match (paramType,@"\W"+className.Trim ()+@"$") ;
					if (m.Success )
						return true;

					//check if the type of the param is like the type of one of the bases
									
					EditPoint st=theClass.StartPoint .CreateEditPoint ();
					monitor .UpdateEditPoint (ref st);
					EditPoint end=theClass.EndPoint.CreateEditPoint ();
					monitor .UpdateEditPoint (ref end);
					string strClass=st.GetText (end );	
					
					string strBases=CodeInspector.GetBases (className,strClass,codeGenerator);
					ArrayList basesNames=CodeInspector .ExtractBasesNames (strBases,codeGenerator );
					for (int i=0;i<basesNames.Count ;i++)
					{
						string baseClass=((string)basesNames[i]).Trim ();
						if (paramType.Length >baseClass.Length )
						{
							if (Regex.Match (paramType,@"(\W|^)"+baseClass+"$").Success )
								return true;
						}
						else
						{
							if (Regex.Match (baseClass,@"(\W|^)"+paramType+"$").Success )
								return true;
						}
					}
					return false;
				
				}
				/// <summary>
				/// see whether the sysntax of declaring a method that implements an interface method is diffrent from 
				/// the ordinary declaration of a method or not
				/// </summary>
				/// <returns></returns>
				static bool IsMethodImplementInterfaceDiffrent(ICodeGenerator codeGen)
				{
					CodeTypeDeclaration td1=new CodeTypeDeclaration ("theClass");
					CodeMemberMethod mm1=new CodeMemberMethod ();
					mm1.Name ="theMethod";
					mm1.ImplementationTypes .Add ("InterfaceName");
					td1.Members .Add (mm1);

					CodeTypeDeclaration td2=new CodeTypeDeclaration ("theClass");
					CodeMemberMethod mm2=new CodeMemberMethod ();
					mm2.Name ="theMethod";
					td2.Members .Add (mm2);

					string methodImplementDeclar=LanguageEngine .GenerateCodeFromType (td1,codeGen);
					string methodDeclar=LanguageEngine .GenerateCodeFromType (td2,codeGen);
					if (methodImplementDeclar == methodDeclar)
						return false;
					else
						return true;
				}
				
				static public void AddConstructorToClass(CodeClass theClass,CodeFunction theConstructor,EditingMonitor monitor)
				{
					/*REMF*/
					EditPoint ep=theConstructor.StartPoint.CreateEditPoint  ();
					monitor.UpdateEditPoint (ref ep);
					EditPoint end=theConstructor.EndPoint .CreateEditPoint ();
					monitor.UpdateEditPoint (ref end);
					string funcBody=ep.GetText (end);
			
					CodeConstructor constructor=new CodeConstructor ();
					constructor .Attributes = MemberAttributes .Public ;
					constructor .Statements .Add(new CodeSnippetExpression (funcBody));
			
					StringWriter w=new StringWriter ();
					//	codeGenerator .GenerateCodeFromExpression (constructor,w,null );
					TextPoint endText=theClass.GetEndPoint (vsCMPart.vsCMPartWhole  );
					EditPoint endPoint=endText.CreateEditPoint ();
					monitor.StartLog(ref endPoint,false);
					endPoint.LineUp (1);
					endPoint.EndOfLine ();
					endPoint.Insert ("\n");/*Inser*/
					monitor.EndLog(ref endPoint);
			
				}
				static public void AddVariableToClass(CodeClass theClass,CodeVariable  theVariable,EditingMonitor monitor)
				{
					/*check if a variable with the same name exists (query the code model tree)*/
					/*REMF*/
					EditPoint ep=theVariable.GetStartPoint (vsCMPart.vsCMPartBody ).CreateEditPoint  ();
					monitor.UpdateEditPoint (ref ep);
					string varDeclaration="";

					EditPoint end=theVariable.GetEndPoint (vsCMPart.vsCMPartBody ) .CreateEditPoint ();
					monitor.UpdateEditPoint (ref end);
					varDeclaration=ep.GetText (end);
							
					EditPoint endPoint;
					if (theClass.Language == EnvDTE.CodeModelLanguageConstants.vsCMLanguageVB )
					{
						endPoint=theClass.GetEndPoint (vsCMPart.vsCMPartBody ).CreateEditPoint ();
						monitor.StartLog (ref endPoint,false);
						endPoint.Insert ("\n");
						endPoint.Insert (varDeclaration);/*Inser*/
						endPoint.Insert ("\n");
						monitor.EndLog (ref endPoint);
					}
					else
					{

						endPoint=theClass.GetEndPoint (vsCMPart.vsCMPartBody).CreateEditPoint ();
						monitor.UpdateEditPoint (ref endPoint);
						EditPoint ActEnd=endPoint.CreateEditPoint ();
						string str=ActEnd.GetText (endPoint);
						while (Regex.Match (str,@"\s*}\s*").Success !=true)
						{
							if (ActEnd.AtStartOfLine )
								ActEnd.LineUp (1);
							else
								ActEnd.CharLeft (1);

							str=ActEnd.GetText (endPoint);
						}
						monitor.StartLog (ref ActEnd,true);

						//		EditPoint endPoint=theClass.EndPoint.CreateEditPoint();
						
//						endPoint.LineUp (1);/*Error Handling*/ //to move before }
//						endPoint.EndOfLine ();
						ActEnd.Insert ("\n");
						ActEnd.Insert (varDeclaration);/*Inser*/
						ActEnd.Insert ("\n");
						monitor.EndLog (ref ActEnd);
					}
					
				}
				static public void AddAttributeToClass(CodeClass theClass,CodeAttribute theAttribute,EditingMonitor monitor)
				{
					/*check if an attribute with the same name exists (query the code model tree (attribute usage)*/
					/*REMF*/
					EditPoint ep=theAttribute.GetStartPoint (vsCMPart.vsCMPartWhole   ) .CreateEditPoint ();
					monitor.UpdateEditPoint (ref ep);
					//EditPoint ep=theAttribute.StartPoint.CreateEditPoint ();
					//string attributeDeclaration=ep.GetText (theAttribute.EndPoint);
					EditPoint e2=theAttribute.GetEndPoint(vsCMPart.vsCMPartWhole).CreateEditPoint ();
					monitor.UpdateEditPoint (ref e2);
					e2.CharRight (1);

					string attributeDeclaration=ep.GetText (e2);
					//MessageBox.Show (attributeDeclaration);

					EditPoint  endPoint=theClass.GetStartPoint  (vsCMPart.vsCMPartWhole  ).CreateEditPoint ();
				
					//endPoint.LineUp (1);
					//endPoint.EndOfLine ();
					//endPoint.Insert ("\n");
					monitor.StartLog(ref endPoint,false);
					endPoint.Insert (attributeDeclaration);
					endPoint.Insert (" ");/*Inser*/
					monitor.EndLog(ref endPoint);
				}
				static private void AddInterfaceToClass(CodeClass theClass,CodeInterface theInterface,XmlNode addedNode,CodeModelBuilder AdvisedCodeModelTree,ICodeGenerator codeGen,EditingMonitor monitor)
				{
					//change the bases of the class
					AddToBases(theClass,theInterface.Name ,true,codeGen,monitor );
		
					//compare the functions in the aspect with the functions in the interface
					//use add method to class

					//add the interface methods to the class
					XmlNodeList methodsNodes=AdvisedCodeModelTree.SearchForElements ("//interface[@name='"+theInterface.Name +"']/methods/method");
					string aspectName=addedNode.Attributes ["aspect"].Value ;
					foreach (XmlNode methodNode in methodsNodes )
					{
						string methodName=methodNode.Attributes ["name"].Value ;
						string methodAccess=methodNode.Attributes ["access"].Value ;
						string methodReturn=methodNode.Attributes ["return"].Value ;
						CodeFunction interfaceMethod=(CodeFunction)AdvisedCodeModelTree.SearchForElement("//aspect[@name='"+aspectName+"']/descendant::method[@name='"+methodName+"'][@access='"+methodAccess +"'][@return='"+methodReturn+"']");
						if (interfaceMethod ==null)/*Error Handling*/ //the aspect desn't contain the implemented interface function
							continue;
						else
						{
							AddMethodToClass(theClass,interfaceMethod,true,theInterface.Name ,codeGen,monitor );
						}
					}
				}
				static public void AddClassToNamespace(EnvDTE.CodeNamespace theNamespace,CodeClass theClass,EditingMonitor monitor)
				{
					/*REMF*/
					EditPoint st=theClass.GetStartPoint (vsCMPart.vsCMPartWholeWithAttributes ).CreateEditPoint ();
					monitor.UpdateEditPoint (ref st);
					EditPoint end=theClass.GetEndPoint (vsCMPart .vsCMPartWholeWithAttributes ).CreateEditPoint ();
					monitor.UpdateEditPoint (ref end);
					string classstr=st.GetText (end);

					EditPoint endPoint=theNamespace.GetEndPoint (vsCMPart.vsCMPartWhole  ).CreateEditPoint ();
					monitor.StartLog(ref endPoint,false);
					endPoint.LineUp (1);
					endPoint.EndOfLine ();
				
					endPoint.Insert ("\n");
					endPoint.Insert (classstr);/*Inser*/
					monitor.EndLog(ref endPoint);
				}
				static public void AddInterfaceToNamespace(EnvDTE.CodeNamespace theNamespace,CodeInterface theInterface,EditingMonitor monitor)
				{
					/*REMF*/
					EditPoint st=theInterface.GetStartPoint (vsCMPart.vsCMPartWhole).CreateEditPoint ();
					monitor.UpdateEditPoint (ref st);
					EditPoint end=theInterface.GetEndPoint (vsCMPart .vsCMPartWhole ).CreateEditPoint ();
					monitor.UpdateEditPoint (ref end);
					string strInterface=st.GetText (end);

					EditPoint endPoint=theNamespace.GetEndPoint (vsCMPart.vsCMPartWhole  ).CreateEditPoint ();
					monitor.StartLog(ref endPoint,false);
					endPoint.LineUp (1);
					endPoint.EndOfLine ();
				
					endPoint.Insert ("\n");
					endPoint.Insert (strInterface );/*Inser*/
					monitor.EndLog(ref endPoint);
				}
			}




		}
	}
